#include "fileMangent.h"
#include <QDebug>
#include "Data/Model_Base.h"
std::condition_variable wait_cond_;
std::mutex wait_mutex_;
std::mutex files_map_mutex;
bool ready = false;
FileMangent::FileMangent()
{
    std::thread setworker(&setuptask_thread::run, &set_works,this);
    setworker.detach();
}
bool FileMangent::can_open_stream() {
    // 在这里我们使用了 std::lock_guard，因为我们只需要短暂地锁定互斥量
    std::lock_guard<std::mutex> lock(files_map_mutex);
    return m_files_map.size() < 5;
}
bool FileMangent::resetAndReadFrames()
{
   if(m_work_finish == false){
    std::cout <<"m_work_finish is false"<<std::endl;
    return false;
   }
   if(m_current_filename.empty()){
     std::cout <<"m_current_filename is empty"<<std::endl;
    return false;
   }
   std::unique_lock<std::mutex> lk(wait_mutex_);

   auto it = m_files_format.find(m_current_filename);
    if (it != m_files_format.end()) {
        auto& format_context_wrapper = it->second;
        audio_queue.flush();
        video_queue.flush();
        int audio_stream_index = format_context_wrapper->get_audio_stream_index();
        int video_stream_index = format_context_wrapper->get_video_stream_index();
        std::cout <<"resetAndReadFrames --------- audio_stream_index "<<audio_stream_index<<" and video_stream_index "<<video_stream_index<<std::endl;
        //avformat_reset_protocol_buffers
        if(format_context_wrapper->seek_frame(audio_stream_index, 0, AVSEEK_FLAG_BACKWARD) == false ||
           format_context_wrapper->seek_frame(video_stream_index, 0, AVSEEK_FLAG_BACKWARD) == false){
            std::cout <<"resetAndReadFrames seek_frame error "<<std::endl;
            return false;
        }
        else{

        }
        avcodec_flush_buffers(audio_codec_context_.get());
        avcodec_flush_buffers(video_codec_context_.get());
        format_context_wrapper->check_stream_status();
        AVPacket packet;
        format_context_wrapper->reset();
        while(format_context_wrapper->read_frame(packet) == true){
             if (packet.stream_index == audio_stream_index) {
                 // 将 AVPacket 添加到音频队列
                 audio_queue.put(&packet);
             } else if (packet.stream_index == video_stream_index) {
                 // 将 AVPacket 添加到视频队列
                 video_queue.put(&packet);
             }
           av_packet_unref(&packet);
        }
        std::cout <<__FUNCTION__<<"Media packet audio-queue "<<audio_queue.size()<<"-"
                 <<video_queue.size()<<std::endl;
    } else {
        std::cout <<"m_files_format is empty"<<std::endl;
        return false;
    }
    return true;
}
void FileMangent::setuptask_thread::run(FileMangent* file_mangent)
{
//    std::cout <<" this is run thread "<<std::endl;
    start_thread_ = true;

    AVPacketManager& audio_queue = file_mangent->get_audio_queue();
    AVPacketManager& video_queue = file_mangent->get_video_queue();
    AVFormatContextWrapper::AVCodecContextPtr audio_codec_ctx;
    AVFormatContextWrapper::AVCodecContextPtr video_codec_ctx;
    audio_queue.init();
    audio_queue.set_type_name("audio");
    video_queue.init();
    video_queue.set_type_name("video");
    while(start_thread_)
    {
      // Wait until main() sends data
      std::unique_lock<std::mutex> lk(wait_mutex_);
      wait_cond_.wait(lk, []{return ready;});
      ready = false;  // Add this line to reset 'ready' after the condition is met
     // 检查是否允许打开新流
     if (file_mangent->can_open_stream()) {
         file_mangent->new_format_ctx_wrapper.open();
         int audio_stream_index = file_mangent->new_format_ctx_wrapper.get_audio_stream_index();
         int video_stream_index = file_mangent->new_format_ctx_wrapper.get_video_stream_index();
         if (audio_stream_index != -1) {
             // 处理音频流
             // 打开音频解码器
             audio_codec_ctx = file_mangent->new_format_ctx_wrapper.open_decoder(audio_stream_index);
         }
         if (video_stream_index != -1) {
             // 处理视频流
            // 打开视频解码器
             video_codec_ctx = file_mangent->new_format_ctx_wrapper.open_decoder(video_stream_index);
         }
         if(audio_codec_ctx ==nullptr|| video_codec_ctx ==nullptr){
             std::cout <<"nullptr nullptr "<<std::endl;
             return ;
         }

         // 将文件信息发送给 MainWindow
         // Dump the input format information
          std::cout <<"----------------------------"<<std::endl;
         // 读取AVPacket并将其添加到队列
         AVPacket packet;
         while (file_mangent->new_format_ctx_wrapper.read_frame(packet)) {
        //     std::cout <<"stream_index -while::"<<packet.stream_index<<std::endl;
             // 根据需要添加逻辑以确定将AVPacket对象添加到哪个队列
             // 例如:
             if (packet.stream_index == audio_stream_index) {
                 // 将 AVPacket 添加到音频队列
                 audio_queue.put(&packet);
             } else if (packet.stream_index == video_stream_index) {
                 // 将 AVPacket 添加到视频队列
                 video_queue.put(&packet);
             }
           av_packet_unref(&packet);
         }
         FileInfo info;
         file_mangent->updateFileInfo(info, std::move(audio_codec_ctx), std::move(video_codec_ctx));
         std::cout <<"Media packet audio-queue "<<audio_queue.size()<<"-"
                  <<video_queue.size()<<std::endl;

         emit file_mangent->fileInformationReceived(info);
         file_mangent->m_current_filename = info.filename;
         file_mangent->m_work_finish.store(true);
     } else {
         // 如果超过了打开流的限制，可以选择稍后重试或者做其他处理
         // 例如：等待一段时间后再次尝试
         std::this_thread::sleep_for(std::chrono::seconds(1));
     }
   }
}
void FileMangent::onPlaybackStopped()
{
  std::cout <<"FileMangent::onPlaybackStopped"<<std::endl;
//  CleanAll();
}
void FileMangent::onPlaybackStarted()
{
  std::cout <<"FileMangent::onPlaybackStarted"<<std::endl;
  if(this->m_work_finish == true && !m_current_filename.empty())
  {
    //find m_files_map m_current_filename ,if find ,emit fileInformationReceived
 //   this->resetAndReadFrames();
    auto iter = m_files_map.find(m_current_filename);
    if(iter != m_files_map.end()){
      emit fileInformationReceived(iter->second);
    }
  }
}
//set Operation
bool FileMangent::addfile(const std::string & filename){
  if(!filename.empty() && filename != m_current_filename)
  {
      new_format_ctx_wrapper.reset();
      new_format_ctx_wrapper.set_name(filename);
      std::unique_lock<std::mutex> lk(wait_mutex_);
      m_current_filename = "";
      m_work_finish.store(false); 
      ready = true;
      wait_cond_.notify_one();
      std::cout<< "input new file :"<<filename<<std::endl;
  }
  return true;
}
bool FileMangent::setcurrentfile(const std::string &filename)
{
   std::unique_lock<std::mutex> lk(wait_mutex_);
   m_current_filename = filename;
   return true;
}

/**
 * @brief 从文件信息列表中删除指定的文件对象
 * @param fileobject 要删除的文件对象
 * @return 删除文件对象是否成功
 */
bool FileMangent::removefile(AVFormatContextWrapper & fileobject)
{
  std::unique_lock<std::mutex> lock(files_map_mutex); // 使用互斥量保护 files_map 的访问

  return false; // 如果找不到文件，返回 false
}
/**
 * @brief 从文件信息列表中删除指定文件名的文件对象
 * @param filename 要删除的文件名
 * @return 删除文件对象是否成功
 */
bool FileMangent::removefile(const std::string &filename) {

    return false; // 如果找不到文件，返回 false
}

/**
 * @brief 清空文件信息列表中的所有文件对象
 */
void FileMangent::CleanAll()
{
  std::unique_lock<std::mutex> lock(files_map_mutex); // 使用互斥量保护 files_map 的访问


  //if file_map is not empty,clear it
  if(!m_files_format.empty())
  {
    m_files_format.clear();
  }
  //clear m_files_map
  if(!m_files_map.empty())
  {
    m_files_map.clear();
  }
  m_current_filename.clear();
  audio_queue.flush();
  video_queue.flush();
  m_work_finish.store(false);
}
/**
 * @brief 获取当前文件名
 * @return 当前文件名
 */
const std::string & FileMangent::getcurrentfile()
{
  return m_current_filename;
}
/**
 * @brief 获取文件信息列表中文件对象的数量
 * @return 文件对象数量
*/
size_t FileMangent::getfilecount()
{
  return m_files_map.size();
}
/**
 * @brief 更新当前文件的信息，并将解码器上下文移动到文件管理对象
 * @param info FileInfo 对象的引用，存储从新的格式上下文提取的文件信息
 * @param audio_codec_ctx 音频解码器上下文的智能指针，将被移动到文件管理对象
 * @param video_codec_ctx 视频解码器上下文的智能指针，将被移动到文件管理对象
 */
void FileMangent::updateFileInfo(FileInfo& info,
                                 AVFormatContextWrapper::AVCodecContextPtr audio_codec_ctx,
                                 AVFormatContextWrapper::AVCodecContextPtr video_codec_ctx) {
    info.filename = new_format_ctx_wrapper.get_name();
    info.duration = new_format_ctx_wrapper.duration();
    info.bitrate = new_format_ctx_wrapper.bit_rate();
    info.media_type = new_format_ctx_wrapper.get_media_type();
    info.audio_type = new_format_ctx_wrapper.get_audio_type();
    info.audio_stream_index = new_format_ctx_wrapper.get_audio_stream_index();
    info.video_stream_index = new_format_ctx_wrapper.get_video_stream_index();
    info.audio_type_avg_frame_rate = new_format_ctx_wrapper.get_audio_type_avg_frame_rate();
    info.video_type_avg_frame_rate = new_format_ctx_wrapper.get_video_type_avg_frame_rate();
    info.audio_type_time_base = new_format_ctx_wrapper.get_audio_type_time_base_double();
    info.video_type_time_base = new_format_ctx_wrapper.get_video_type_time_base_double();
    info.audio_frame_size = new_format_ctx_wrapper.get_audio_frame_size();
    // std::cout << "new_format_ctx_wrapper.get_stream(new_format_ctx_wrapper.get_audio_stream_index())->avg_frame_rate" << new_format_ctx_wrapper.get_stream(new_format_ctx_wrapper.get_audio_stream_index())->avg_frame_rate.num <<std::endl;
    // std::cout << "new_format_ctx_wrapper.get_stream(new_format_ctx_wrapper.get_audio_stream_index())->avg_frame_rate" << new_format_ctx_wrapper.get_stream(new_format_ctx_wrapper.get_audio_stream_index())->avg_frame_rate.den <<std::endl;
    // std::cout << "audio_type_avg_frame_rate" << info.audio_type_avg_frame_rate <<"---"<< av_q2d(new_format_ctx_wrapper.get_stream(new_format_ctx_wrapper.get_audio_stream_index())->avg_frame_rate)<<std::endl;
    // std::cout << "audio_type_time_base" << info.audio_type_time_base <<"---"<< av_q2d(new_format_ctx_wrapper.get_stream(new_format_ctx_wrapper.get_audio_stream_index())->time_base)<<std::endl;
    // std::cout << "video_type_time_base" << info.video_type_time_base <<"---"<< av_q2d(new_format_ctx_wrapper.get_stream(new_format_ctx_wrapper.get_video_stream_index())->time_base)<<std::endl;
    m_files_map[info.filename] = info;
    m_files_format[info.filename] = std::unique_ptr<AVFormatContextWrapper>(new AVFormatContextWrapper(std::move(new_format_ctx_wrapper)));
    audio_codec_context_ = std::move(audio_codec_ctx);
    video_codec_context_ = std::move(video_codec_ctx);
}

